/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
// Copyright tang.  All rights reserved.
// https://gitee.com/inrgihc/dbswitch
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2020/1/2
// Location: beijing , china
/////////////////////////////////////////////////////////////
package com.je.meta.service.dbswitch.service;

import com.je.ibatis.extension.plugins.pagination.Page;
import com.je.meta.model.database.*;
import com.je.meta.model.database.type.ProductTypeEnum;

import java.sql.Connection;
import java.util.List;

/**
 * 数据库访问通用业务接口
 *
 * @author tang
 */
public interface IDatabaseInterface {

    /**
     * 获取数据库类型
     *
     * @return 数据库类型
     */
    ProductTypeEnum getDatabaseType();

    /**
     * 获取数据库的模式schema列表
     *
     * @param connection JDBC连接
     * @return 模式名列表
     */
    List<String> querySchemaList(Connection connection);

    /**
     * 获取指定模式Schema内的所有表列表
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @return 表及视图名列表
     */
    Page queryTableList(Connection connection, String schemaName, String productId, String fuzzyValue,
                        int intPage, int intLimit);

    List<TableDescription> queryTableList(Connection connection, String schemaName);

    /**
     * 设置表主键自增策略
     *
     * @param pks
     * @param columns
     */
    void buildTableKeyGenerator(TableDescription td, List<String> pks, List<ColumnDescription> columns);

    /**
     * 精确获取表或视图的元数据
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表或视图名称
     * @return
     */
    TableDescription queryTableMeta(Connection connection, String schemaName, String tableName);

    /**
     * 获取指定物理表的DDL语句
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表名称
     * @return 字段元信息列表
     */
    String getTableDDL(Connection connection, String schemaName, String tableName);

    /**
     * 获取指定视图表的DDL语句
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表或视图名称
     * @return 字段元信息列表
     */
    String getViewDDL(Connection connection, String schemaName, String tableName);

    /**
     * 获取指定模式表的元信息
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表或视图名称
     * @return 字段元信息列表
     */
    List<ColumnDescription> queryTableColumnMeta(Connection connection, String schemaName,
                                                 String tableName);

    /**
     * 获取指定查询SQL的元信息
     *
     * @param connection JDBC连接
     * @param sql        SQL查询语句
     * @return 字段元信息列表
     */
    List<ColumnDescription> querySelectSqlColumnMeta(Connection connection, String sql);

    /**
     * 获取指定模式表的主键字段列表
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表名称
     * @return 主键字段名称列表
     */
    List<String> queryTablePrimaryKeys(Connection connection, String schemaName, String tableName);

    /**
     * 获取指定模式表内的数据
     *
     * @param connection JDBC连接
     * @param schemaName 模式名称
     * @param tableName  表名称
     * @param rowCount   记录的行数
     * @return 数据内容
     */
    SchemaTableData queryTableData(Connection connection, String schemaName, String tableName,
                                   int rowCount);

    /**
     * 测试查询SQL语句的有效性
     *
     * @param connection JDBC连接
     * @param sql        待验证的SQL语句
     */
    void testQuerySQL(Connection connection, String sql);

    /**
     * 获取数据库的表全名
     *
     * @param schemaName 模式名称
     * @param tableName  表名称
     * @return 表全名
     */
    String getQuotedSchemaTableCombination(String schemaName, String tableName);

    /**
     * 获取字段列的结构定义
     *
     * @param v           值元数据定义
     * @param pks         主键字段名称列表
     * @param addCr       是否结尾换行
     * @param useAutoInc  是否自增
     * @param withRemarks 是否带有注释
     * @return 字段定义字符串
     */
    String getFieldDefinition(ColumnMetaData v, List<String> pks, boolean useAutoInc, boolean addCr,
                              boolean withRemarks);

    /**
     * 主键列转换为逗号分隔的字符串
     *
     * @param pks 主键字段列表
     * @return 主键字段拼接串
     */
    String getPrimaryKeyAsString(List<String> pks);

    /**
     * 获取表和字段的注释定义
     *
     * @param td  表信息定义
     * @param cds 列信息定义
     * @return 定义字符串列表
     */
    List<String> getTableColumnCommentDefinition(TableDescription td, List<ColumnDescription> cds);

    /**
     * 获取表外键信息
     *
     * @param connection 连接信息
     * @param schemaName 库名
     * @param tableName  表名
     * @param tableMeta  tableMeta信息
     * @return
     */
    List<ImportedKeyData> getTableImportedKeyData(Connection connection, String schemaName, String tableName, SchemaTableMeta tableMeta);

    /**
     * 获取表索引信息
     *
     * @param connection 连接信息
     * @param schemaName 库名
     * @param tableName  表名
     * @param columns    字段信息
     * @return
     */
    List<IndexesData> getTableIndexesDataData(Connection connection, String schemaName, String tableName, List<ColumnDescription> columns);

    /**
     * 修改JETableMeta信息
     *
     * @param list      表元数据信息
     * @param syParent  上级目录
     * @param productId 产品id
     * @return
     */
    void updateJeTableMetaBySchemaTableMeta(List<SchemaTableMeta> list, String syParent, String productId);

}
